/*
--------------------------------------------------------------------------------
				Ak-Lib. 
			 Project       	: Ak-Lib
			 Group         	: Ak-Lib R&D Team
			 Author        	: Ocean.Wang
			 Create Date 	: 05-01-2010
--------------------------------------------------------------------------------
Code Name 	:  A.K 	~v~
Description	:  Yet Another Cross-Platform Lib.
Cautions    	:
--------------------------------------------------------------------------------
Change History:
Version		: 0.1
Building 		: 05/01/10
10-05.01 first draft, build, debug and test.
--------------------------------------------------------------------------------
*/
#ifndef	_INC_AK_TASK_
#define	_INC_AK_TASK_

#include "ak_types.h"

#ifdef __cplusplus
extern "C" {
#endif

#define 	STASK_NAME_MAX 	31
/* Linux */
#if 	_TARGET_OS == _OS_GNU
typedef pthread_t 	_t_sysTask;
typedef void * 		(SYS_CALLBACK * _TASKENTRY)(void *);	

typedef struct{
	pid_t					pid;
	pid_t					tid;
}_t_sysTaskAttr;

#include <syscall.h>
#define STask_Attr(vAttr) \
do{ \
	(vAttr)->pid = getpid();\
	(vAttr)->tid = syscall(SYS_gettid);\
}while(0)

/* ---------------------------------------------------------------------------
** 	Thread Naming
*/
#include <sys/prctl.h>
#define STASK_SETNAME(sName)   prctl(PR_SET_NAME, sName, 0,0,0)

static 	__inline 	int 	STask_SetName(const char * fmt, ...)
{
	char 	sName[STASK_NAME_MAX+1];

	int 			ret;
	va_list 		va;
	if(fmt){
		va_start(va, fmt);
		ret = vsnprintf(sName, STASK_NAME_MAX, fmt, va);
		va_end(va); 
		if((ret > -1) && (ret < STASK_NAME_MAX)){
			sName[ret] = '\0';
			STASK_SETNAME(sName);
			return 0;
		}
	}		
	return -1;
}

/* Windows */
#elif 	_TARGET_OS == _OS_WIN
#ifdef _BORLAND_
#include <stdint.h>
#define STask_SetName(fmt...)
#else
#define STask_SetName(fmt, ...)
#endif

typedef uintptr_t 	_t_sysTask;
typedef unsigned int 	(SYS_CALLBACK * _TASKENTRY)(void *);	

typedef struct{
	HANDLE					pid;
	HANDLE					tid;
}_t_sysTaskAttr;

#define STask_Attr(vAttr) \
do{ \
	(vAttr)->pid = GetCurrentProcess();\
	(vAttr)->tid = GetCurrentThread();\
}while(0)
	
#endif

extern	void 	STask_LibInit(void);
extern	_t_sysTask 	STask_Spawn(_TASKENTRY 	  	entry,
						void * 				param,
						int 				stackSize, 
						int 				priority);
extern	void 	STask_Suspend(_t_sysTask   tid);
extern 	void 	STask_Resume(_t_sysTask 	tid);
extern	void 	STask_Delete(_t_sysTask  	tid);
extern 	void 	STask_PriSet(_t_sysTask  	tid, int nPri);


#define 	STASK_CRATE(vTask, vStackSize, vPri, vEntry, vParam) \
do{\
	vTask = STask_Spawn((_TASKENTRY)(vEntry),\
							vParam,		\
							vStackSize, \
							vPri); 		\
	if(vTask){\
		STask_PriSet(vTask, vPri);\
	 	STask_Resume(vTask);\
	}\
}while(0)



#ifdef __cplusplus
}
#endif


#endif



